package com.jf.cloud.service.sysmanager.common.base;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.jf.cloud.service.sysmanager.common.db.SqlUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.BeanPropertyRowMapper;

import com.jf.cloud.service.sysmanager.common.db.BaseDao;
import com.jf.cloud.service.sysmanager.common.db.Query;
import com.jf.cloud.service.sysmanager.common.taglib.Paging;
import com.jf.cloud.service.sysmanager.common.util.BeanUtil;
import com.jf.cloud.service.sysmanager.constant.TagConstant;

/**
 * 泛型DAO 需要明确指定泛型 否则无法正常运行
 * 建议使用范围：独立业务service
 * 
 * @author 朱建文 创建时间：2017年12月6日 下午4:30:16
 */
@SuppressWarnings("all")
public class BaseService<T extends Serializable,PK extends Serializable> extends JframeService<T, PK> implements IBaseService<T,PK> {
static Logger logger = LoggerFactory.getLogger(BaseService.class);
	
	@Resource
	private BaseDao baseDao;
	
	private Class<T> clazz;
	
	@SuppressWarnings("all")
	public BaseService(){  
        clazz= GenericsUtils.getSuperClassGenricType(this.getClass());
    }
	public T find( String colnumName, Object colnumValue) {
		String tableName = BeanUtil.getTableName(clazz);
		String sql = " select * from "+tableName+" where "+colnumName+"=?";
		T t =null;
		try {
			t =baseDao.findObject(sql, new BeanPropertyRowMapper<T>(clazz), colnumValue);
		} catch (Exception e) {
			logger.info("查询失败 不存在对应的数据");
		} 
		return t;
	}
	
	public T find( Query query) {
		String tableName = BeanUtil.getTableName(clazz);
		StringBuffer sf = new StringBuffer(120);
		sf.append(query.getSQL(" select * from " + tableName)); 

		String whereSQL = query.getWhereSQL();
		T rs = null;
		if(StringUtils.isNotBlank(whereSQL)) {
			rs = baseDao.findObject(sf.toString(), new BeanPropertyRowMapper<T>(clazz), query.getParamList().toArray());
		}
		return rs;
	}

	public T find(Map<String,String> columns, Query query) {
		String tableName = BeanUtil.getTableName(clazz);
		if (!(columns != null && columns.size() > 0)) {
			throw new IllegalArgumentException("表名与查询字段不能为空");
		}
		StringBuffer sb = new StringBuffer();
		sb.append(" SELECT ");
		for (Map.Entry<String, String> column : columns.entrySet()) {
			if (sb.length() > 8) {
				sb.append(", ");
			}
			if (column.getKey() != null && column.getValue() != null && column.getValue().length() > 0) {
				sb.append(column.getKey());
				sb.append(" AS ");
				sb.append(column.getValue());
			} else {
				sb.append(column.getKey());
			}
		}
		sb.append(" FROM ").append(tableName);
		StringBuffer sf = new StringBuffer(120);
		sf.append(query.getSQL(sb.toString()));

		String whereSQL = query.getWhereSQL();
		T rs = null;
		if(StringUtils.isNotBlank(whereSQL)) {
			rs = baseDao.findObject(sf.toString(), new BeanPropertyRowMapper<T>(clazz), query.getParamList().toArray());
		}
		return rs;
	}
	
	public <T> T findSingleColumnObject(Query query,Class<T> clazzType ) {
		String tableName = BeanUtil.getTableName(clazz);
		StringBuffer sf = new StringBuffer(120);
		sf.append(query.getSQL(" select count(*) from " + tableName)); 

		//String whereSQL = query.getWhereSQL();
		T rs = null;
	//	if(StringUtils.isNotBlank(whereSQL)) {
			rs = baseDao.findSingleColumnObject(sf.toString(), clazzType, query.getParamList().toArray());
		//}
		return rs;
	}
	
	public T findByPK(PK pkVal) {
		return find("ROW_ID",pkVal); 
	}
	public List<T> findList( Query query) {
		String tableName = BeanUtil.getTableName(clazz);
		StringBuffer sf = new StringBuffer(120);
		sf.append(query.getSQL(" select * from " + tableName)); 

		String whereSQL = query.getWhereSQL();
		List<T> rs = null;
		if(StringUtils.isNotBlank(whereSQL)) {
			rs = baseDao.findList(sf.toString(), new BeanPropertyRowMapper<T>(clazz), query.getParamList().toArray());
		}
		return rs;
	}
	
	public List<T> findList( String colnumName, Object colnumValue) {
		String tableName = BeanUtil.getTableName(clazz);
		String sql = " select * from "+tableName+" where "+colnumName+"=?";
		return baseDao.findList(sql, new BeanPropertyRowMapper<T>(clazz), colnumValue);
	}

	public List<T> findList(Map<String, String> columns, Query query) {
		String tableName = BeanUtil.getTableName(clazz);
		if (!(columns != null && columns.size() > 0)) {
			throw new IllegalArgumentException("表名与查询字段不能为空");
		}
		StringBuffer sb = new StringBuffer(120);
		sb.append(" SELECT ");
		for (Map.Entry<String, String> column : columns.entrySet()) {
			if (sb.length() > 8) {
				sb.append(", ");
			}
			if (column.getKey() != null && column.getValue() != null && column.getValue().length() > 0) {
				sb.append(column.getKey());
				sb.append(" AS ");
				sb.append(column.getValue());
			} else {
				sb.append(column.getKey());
			}
		}
		sb.append(" FROM ").append(tableName);

		String whereSQL = query.getWhereSQL();
		List<T> rs = null;
		if(StringUtils.isNotBlank(whereSQL)) {
			rs = baseDao.findList(query.getSQL(sb.toString()), new BeanPropertyRowMapper<T>(clazz), query.getParamList().toArray());
		}
		return rs;
	}
	
	public Map<String, Object> findMap(Map<String, String> columns, Query query) {
		List<Map<String, Object>> ls = findMapList(columns, query);
		return ls == null || ls.size() == 0 ? null : ls.get(0);
	}
	
	public Map<String, Object> findMap(Query query) {
		List<Map<String, Object>> ls = findMapList(query);
		return ls == null || ls.size() == 0 ? null : ls.get(0);
	}
	
	public List<Map<String, Object>> findMapList(Query query) {
		String tableName = BeanUtil.getTableName(clazz);
		
		StringBuffer sb = new StringBuffer(120);
		sb.append(" SELECT * ");
		sb.append(" FROM ").append(tableName);
		String whereSQL = query.getWhereSQL();
		List<Map<String, Object>> rs = null;
		if(StringUtils.isNotBlank(whereSQL)) {
			rs = baseDao.findMapList(query.getSQL(sb.toString()), query.getParamList().toArray());
		}
		return rs;
	}
	
	public List<Map<String, Object>> findMapList(Map<String, String> columns, Query query) {
		String tableName = BeanUtil.getTableName(clazz);
		if (!(columns != null && columns.size() > 0)) {
			throw new IllegalArgumentException("表名与查询字段不能为空");
		}
		StringBuffer sb = new StringBuffer(120);
		sb.append(" SELECT ");
		for (Map.Entry<String, String> column : columns.entrySet()) {
			if (sb.length() > 8) {
				sb.append(", ");
			}
			if (column.getKey() != null && column.getValue() != null && column.getValue().length() > 0) {
				sb.append(column.getKey());
				sb.append(" AS ");
				sb.append(column.getValue());
			} else {
				sb.append(column.getKey());
			}
		}
		sb.append(" FROM ").append(tableName);

		String whereSQL = query.getWhereSQL();
		List<Map<String, Object>> rs = null;
		if(StringUtils.isNotBlank(whereSQL)) {
			rs = baseDao.findMapList(query.getSQL(sb.toString()), query.getParamList().toArray());
		}
		return rs;
	}
	/**
	 * 优化单表查询的 分页查询
	 * 去掉字段，去掉排序
	 */
	public Paging<T> findPage( Paging<T> page) {
		String tableName = BeanUtil.getTableName(clazz);
		StringBuffer sql = new StringBuffer();
		String findSql = " select * from  ";
		String countSql = " select count(1) from  ";
		sql.append(tableName);
		sql.append(page.getWhereSQL(true));
		List<Object> param = page.getParamList();
		countSql +=sql.toString(); 
		sql.append(page.getOthers());
		sql.append(page.getOrderBy());
		findSql+=sql.toString();
		
		return this.baseDao.findListByPage(findSql,countSql, new BeanPropertyRowMapper<T>(clazz), page, param.toArray());

	}

	/**
	 * 分页查询List,自定义查询字段
	 * key:字段名  value:别名
	 */
	public Paging<T> findPage(Map<String, String> columns, Paging<T> page) {
		String tableName = BeanUtil.getTableName(clazz);
		if (!(columns != null && columns.size() > 0)) {
			throw new IllegalArgumentException("表名与查询字段不能为空");
		}
		StringBuffer sb = new StringBuffer();
		sb.append(" SELECT ");
		for (Map.Entry<String, String> column : columns.entrySet()) {
			if (sb.length() > 8) {
				sb.append(", ");
			}
			if (column.getKey() != null && column.getValue() != null && column.getValue().length() > 0) {
				sb.append(column.getKey());
				sb.append(" AS ");
				sb.append(column.getValue());
			} else {
				sb.append(column.getKey());
			}
		}
		sb.append(" FROM ").append(tableName);
		sb.append(page.getWhereSQL(true));
		sb.append(page.getOrderBy());
		List<Object> param = page.getParamList();
		String countSql = SqlUtil.getPageCountSQL(sb.toString());
		return this.baseDao.findListByPage(sb.toString(),countSql, new BeanPropertyRowMapper<T>(clazz), page, param.toArray());

	}
	
	public boolean isExist( Query query) {
		String tableName = BeanUtil.getTableName(clazz);
		try {
			if (query != null &&  query.getParamList().size() > 0) {
				String sql = query.getSQL("SELECT COUNT(0) FROM " + tableName);
				return baseDao.findCount(sql, query.getParamList().toArray()) > 0;
			}
		} catch (Exception e) {
			logger.error("根据实体类、查询条件判断是否存在出错了！", e);
		}
		return false;
	}
	/**
	 * 多条件查询
	 * textColumn:显示的字段
	 * valColumn ：取值的字段
	 * query ： 查询条件
	 */
	public List<Map<String, Object>> findForTags(String textColumn, String valColumn, Query query) {
		String tableName = BeanUtil.getTableName(clazz);
		String sql = " select "+valColumn+" as "+TagConstant.DICT_OPTION_VALUE_KEY+" ,"+ textColumn+" as "+TagConstant.DICT_OPTION_LABEL_KEY+"  from "+tableName;
		if (query != null &&  query.getParamList().size() > 0) {
			sql = query.getSQL(sql);
			return baseDao.findMapList(sql, query.getParamList().toArray());
		}
		return baseDao.findMapList(sql);
	} 
	public int update(String sql, Object... args){
		return baseDao.update(sql, args);
	}
	public T saveObj(T obj) { 
		return baseDao.saveAll(obj);
	}
	/**
	 * ★ 根据SQL语句及参数执行保存、更新或删除 【无事物，不关心结果的修改，有风险的】
	 */
	public int updateRisk(String sql, Object... args){
		return baseDao.updateRisk(sql, args);
	}

	/**
	 * 执行修改语句！返回执行结果 boolean (指定必须影响的行数)
	 * @param mustUpdateRecords 预期的执行影响条数 如果大于0 并且和执行结果不相等则抛出异常 (null 或者 0 则不做要求)
	 * @author 卫江波
	 * @2017年6月27日下午4:54:48
	 */
	public Boolean safeUpdate(String sql, int mustUpdateRecords, Object... args){
		return baseDao.safeUpdate(sql, mustUpdateRecords, args); 
	}
}
